package com.ruoyi.relationOrder.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.distributionConfig.domain.DistributionConfig;
import com.ruoyi.distributionConfig.service.IDistributionConfigService;
import com.ruoyi.income.domain.DistributionIncome;
import com.ruoyi.income.service.IDistributionIncomeService;
import com.ruoyi.order.domain.Order;
import com.ruoyi.order.service.IRemoteOrderService;
import com.ruoyi.wallet.domain.DistributionWallet;
import com.ruoyi.wallet.service.IDistributionWalletService;
import org.hibernate.validator.internal.util.stereotypes.Lazy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.relationOrder.mapper.DistributionOrderRelationMapper;
import com.ruoyi.relationOrder.domain.DistributionOrderRelation;
import com.ruoyi.relationOrder.service.IDistributionOrderRelationService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 分销订单关联Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-11-07
 */
@Service
public class DistributionOrderRelationServiceImpl implements IDistributionOrderRelationService 
{
    private static final Logger log = LoggerFactory.getLogger(DistributionOrderRelationServiceImpl.class);

    @Autowired
    private DistributionOrderRelationMapper distributionOrderRelationMapper;

    @Autowired
    @Lazy
    private IRemoteOrderService remoteOrderService;

    @Autowired
    private IDistributionIncomeService distributionIncomeService;

    @Autowired
    private IDistributionWalletService distributionWalletService;

    @Autowired
    private IDistributionConfigService distributionConfigService;


    /**
     * 查询分销订单关联的订单信息
     * @param distributionOrderRelation 分销订单关联
     * @return 订单列表
     */
    @Override
    public List<DistributionOrderRelation> selectOrderRelationSummaryList(DistributionOrderRelation distributionOrderRelation) {
        return distributionOrderRelationMapper.selectOrderRelationSummaryList(distributionOrderRelation);
    }

    /**
     * 根据订单ID查询分销订单关联
     * @param orderId 订单ID
     * @return 分销订单关联
     */
    @Override
    public DistributionOrderRelation selectDistributionOrderRelationByOrderId(Long orderId) {
        return distributionOrderRelationMapper.selectDistributionOrderRelationByOrderId(orderId);
    }


    /**
     * 查询指定分销员的待结算分销订单记录
     * @param distributorId 分销员ID
     * @return 分销订单关联列表
     */
    @Override
    public List<DistributionOrderRelation> selectPendingRelationsByDistributorId(Long distributorId) {
        return distributionOrderRelationMapper.selectPendingRelationsByDistributorId(distributorId);
    }



    /**
     * 查询分销订单关联
     * 
     * @param relationId 分销订单关联主键
     * @return 分销订单关联
     */
    @Override
    public DistributionOrderRelation selectDistributionOrderRelationByRelationId(Long relationId)
    {
        return distributionOrderRelationMapper.selectDistributionOrderRelationByRelationId(relationId);
    }

    /**
     * 查询分销订单关联列表
     * 
     * @param distributionOrderRelation 分销订单关联
     * @return 分销订单关联
     */
    @Override
    public List<DistributionOrderRelation> selectDistributionOrderRelationList(DistributionOrderRelation distributionOrderRelation)
    {
        return distributionOrderRelationMapper.selectDistributionOrderRelationList(distributionOrderRelation);
    }

    /**
     * 新增分销订单关联
     * 
     * @param distributionOrderRelation 分销订单关联
     * @return 结果
     */
    @Override
    public int insertDistributionOrderRelation(DistributionOrderRelation distributionOrderRelation)
    {
        distributionOrderRelation.setCreateTime(DateUtils.getNowDate());
        return distributionOrderRelationMapper.insertDistributionOrderRelation(distributionOrderRelation);
    }

    /**
     * 修改分销订单关联
     * 
     * @param distributionOrderRelation 分销订单关联
     * @return 结果
     */
    @Override
    public int updateDistributionOrderRelation(DistributionOrderRelation distributionOrderRelation)
    {
        distributionOrderRelation.setUpdateTime(DateUtils.getNowDate());
        return distributionOrderRelationMapper.updateDistributionOrderRelation(distributionOrderRelation);
    }

    /**
     * 批量删除分销订单关联
     * 
     * @param relationIds 需要删除的分销订单关联主键
     * @return 结果
     */
    @Override
    public int deleteDistributionOrderRelationByRelationIds(Long[] relationIds)
    {
        return distributionOrderRelationMapper.deleteDistributionOrderRelationByRelationIds(relationIds);
    }

    /**
     * 删除分销订单关联信息
     * 
     * @param relationId 分销订单关联主键
     * @return 结果
     */
    @Override
    public int deleteDistributionOrderRelationByRelationId(Long relationId)
    {
        return distributionOrderRelationMapper.deleteDistributionOrderRelationByRelationId(relationId);
    }

    // ... 定时任务（每日凌晨）查询 “待结算” 且满足周期的记录
    // 批量更新返佣状态为 “已可用” 同步钱包可用余额； ...
    /**
     * 定时任务：处理待结算的分销订单
     * 每日凌晨执行，将满足条件的"待结算"记录更新为"已可用"状态，并同步更新钱包余额
     * 注意：如果配置了结算周期为0（立即返佣），此任务将只处理已超过结算周期的订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processSettlementOrders() {
        log.info("开始执行分销订单结算任务");

        try {
            // 获取分销配置，检查是否为立即返佣模式
            DistributionConfig config = distributionConfigService.selectDistributionConfigByConfigId(1L);
            boolean immediateSettlement = false;
            if (config != null && config.getSettlementDays() != null && config.getSettlementDays() == 0) {
                immediateSettlement = true;
                log.info("检测到结算周期为0（立即返佣模式），当前任务将只处理已到期的待结算订单");
            }

            // 1. 查询所有"待结算"状态的分销订单关联记录
            DistributionOrderRelation query = new DistributionOrderRelation();
            query.setDistributionStatus("1"); // 1-待结算
            List<DistributionOrderRelation> pendingSettlementOrders = selectDistributionOrderRelationList(query);

            if (pendingSettlementOrders == null || pendingSettlementOrders.isEmpty()) {
                log.info("没有待结算的分销订单");
                return;
            }

            log.info("找到 {} 条待结算的分销订单", pendingSettlementOrders.size());

            int successCount = 0;
            int failCount = 0;
            for (DistributionOrderRelation relation : pendingSettlementOrders) {
                try {
                    // 2. 检查是否满足结算周期
                    if (isSettlementPeriodPassed(relation)) {
                        // 3. 更新返佣状态为"已结算"
                        relation.setDistributionStatus("2"); // 2-已结算
                        relation.setSettlementTime(new Date()); // 设置结算时间

                        int updateResult = updateDistributionOrderRelation(relation);
                        if (updateResult > 0) {
                            try {
                                // 4. 同步更新钱包可用余额
                                syncWalletBalance(relation);
                                successCount++;
                                log.info("分销订单 {} 结算成功", relation.getRelationId());
                            } catch (Exception e) {
                                // 如果同步钱包失败，回滚订单状态更新
                                relation.setDistributionStatus("1"); // 恢复为待结算状态
                                updateDistributionOrderRelation(relation);
                                throw e;
                            }
                        } else {
                            failCount++;
                            log.warn("分销订单 {} 更新状态失败", relation.getRelationId());
                        }
                    } else if (immediateSettlement) {
                        log.info("立即返佣模式：跳过订单 {}（结算周期为0，但订单未到结算时间）", relation.getRelationId());
                    }
                } catch (Exception e) {
                    failCount++;
                    log.error("处理分销订单 {} 结算时发生异常", relation.getRelationId(), e);
                }
            }

            log.info("分销订单结算任务完成，成功处理 {} 条记录，失败 {} 条记录", successCount, failCount);
        } catch (Exception e) {
            log.error("执行分销订单结算任务时发生异常", e);
            throw new RuntimeException("分销订单结算任务执行失败", e);
        }
    }


    /**
     * 同步更新钱包可用余额
     * @param relation 分销订单关联记录
     */
    private void syncWalletBalance(DistributionOrderRelation relation) {
        try {
            // 1. 查询相关的返佣收入记录
            DistributionIncome incomeQuery = new DistributionIncome();
            incomeQuery.setOrderId(relation.getOrderId());
            List<DistributionIncome> incomeList = distributionIncomeService.selectDistributionIncomeList(incomeQuery);

            if (incomeList == null || incomeList.isEmpty()) {
                log.info("订单 {} 没有相关的返佣收入记录", relation.getOrderId());
                return;
            }

            // 2. 按分销员分组处理
            Map<Long, List<DistributionIncome>> incomeMap = incomeList.stream()
                    .collect(Collectors.groupingBy(DistributionIncome::getDistributorId));

            for (Map.Entry<Long, List<DistributionIncome>> entry : incomeMap.entrySet()) {
                Long distributorId = entry.getKey();
                List<DistributionIncome> distributorIncomes = entry.getValue();

                // 3. 计算该分销员的总返佣金额
                BigDecimal totalRebateAmount = BigDecimal.ZERO;
                List<DistributionIncome> updatedIncomes = new ArrayList<>();

                for (DistributionIncome income : distributorIncomes) {
                    // 只处理待结算状态的收入记录
                    if ("1".equals(income.getIncomeStatus())) {
                        totalRebateAmount = totalRebateAmount.add(income.getRebateAmount());
                        // 更新收入记录状态为已可用
                        income.setIncomeStatus("2"); // 2-已可用
                        updatedIncomes.add(income);
                    }
                }
                if (totalRebateAmount.compareTo(BigDecimal.ZERO) > 0) {
                    // 4. 更新分销员钱包余额
                    DistributionWallet wallet = distributionWalletService.selectWalletByDistributorId(distributorId);
                    if (wallet != null) {
                        // 更新钱包余额
                        updateWalletForSettlement(wallet, totalRebateAmount);

                        // 批量更新收入记录状态
                        for (DistributionIncome income : updatedIncomes) {
                            // 使用系统用户更新，避免获取当前用户信息
                            income.setUpdateTime(new Date());
                            income.setUpdateBy("system-settlement");
                            distributionIncomeService.updateDistributionIncome(income);
                        }

                        log.info("更新分销员 {} 钱包余额成功，增加可用余额: {}", distributorId, totalRebateAmount);
                    } else {
                        log.warn("分销员 {} 的钱包不存在", distributorId);
                    }
                }


//                if (totalRebateAmount.compareTo(BigDecimal.ZERO) > 0) {
//                    // 4. 更新分销员钱包余额
//                    DistributionWallet wallet = distributionWalletService.selectWalletByDistributorId(distributorId);
//                    if (wallet != null) {
//                        // 更新钱包余额
//                        updateWalletForSettlement(wallet, totalRebateAmount);
//
//                        // 批量更新收入记录状态
//                        for (DistributionIncome income : updatedIncomes) {
//                            distributionIncomeService.updateDistributionIncome(income);
//                        }
//
//                        log.info("更新分销员 {} 钱包余额成功，增加可用余额: {}", distributorId, totalRebateAmount);
//                    } else {
//                        log.warn("分销员 {} 的钱包不存在", distributorId);
//                    }
//                }
            }
        } catch (Exception e) {
            log.error("同步更新钱包余额时发生异常，关联ID: {}", relation.getRelationId(), e);
            throw new RuntimeException("同步更新钱包余额失败", e);
        }
    }

    /**
     * 更新钱包余额用于结算
     * @param wallet 钱包
     * @param amount 结算金额
     */
    private void updateWalletForSettlement(DistributionWallet wallet, BigDecimal amount) {
        // 增加可用余额
        wallet.setAvailableBalance(
                wallet.getAvailableBalance() != null ?
                        wallet.getAvailableBalance().add(amount) :
                        amount
        );

        // 减少待结算余额
        wallet.setPendingSettlementBalance(
                wallet.getPendingSettlementBalance() != null ?
                        wallet.getPendingSettlementBalance().subtract(amount) :
                        BigDecimal.ZERO
        );

        // 更新总收益
        wallet.setTotalIncome(
                wallet.getTotalIncome() != null ?
                        wallet.getTotalIncome().add(amount) :
                        amount
        );

        wallet.setLastIncomeTime(new Date());
        wallet.setUpdateTime(new Date());
        wallet.setUpdateBy("system-settlement");

        distributionWalletService.updateDistributionWallet(wallet);
    }


    /**
     * 检查是否满足结算周期（根据配置）
     * @param relation 分销订单关联记录
     * @return 是否满足结算周期
     */
    private boolean isSettlementPeriodPassed(DistributionOrderRelation relation) {
        // 为了测试，暂时总是返回true
        // 实际使用时请注释掉下面这行
        // return true;

        // 获取分销配置
        DistributionConfig config = distributionConfigService.selectDistributionConfigByConfigId(1L);
        Long settlementDays = (config != null && config.getSettlementDays() != null) ?
                config.getSettlementDays() : 7L; // 默认7天

        // 通过远程服务获取订单信息
        Order order = remoteOrderService.selectOrderByOrderId(relation.getOrderId());
        if (order == null || order.getPayTime() == null) {
            log.warn("无法获取订单 {} 的支付时间或订单不存在", relation.getOrderId());
            return false;
        }

        // 计算T+N天的时间点（N为配置的结算天数）
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(order.getPayTime());
        calendar.add(Calendar.DAY_OF_MONTH, settlementDays.intValue());

        // 判断当前时间是否已经超过T+N天
        return new Date().after(calendar.getTime());
    }

}
